package com.ymatou.apigateway.testcase;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.shop2cn.iapi.shenqisettlement.parameter.bean.AgentProductBean;
import com.shop2cn.iapi.sqoptrade.resp.Order;
import com.shop2cn.iapi.sqoptrade.resp.TradingServiceResp;
import com.ymatou.apigateway.parameter.AesUtil;
import com.ymatou.apigateway.parameter.OpenapiReq;
import com.ymatou.apigateway.parameter.SqOverSellFullRefundReq;
import com.ymatou.apigateway.service.OpenapiService;
import com.ymatou.apigateway.service.SqOverSellFullRefundCall;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.SQPayGateWayCallService;
import com.ymttest.business.service.shenqi.DGSQBuildProxyChainCallService;
import com.ymttest.business.service.shenqi.RefundService;
import com.ymttest.business.service.shenqi.ShenqiSettlementService;
import com.ymttest.business.service.shenqi.SqTradingCallService;
import com.ymttest.database.model.Application;
import com.ymttest.database.model.AuthCode;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.PaymentPo;
import com.ymttest.database.sharding.db.sharding.model.UserRefundFundDetailPo;
import com.ymttest.database.model.sqrefund.RefundBill;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.database.sqlwapper.OpenApiWapper;
import com.ymttest.database.sqlwapper.sqrefund.RefundBillWrapper;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.YMTDateUtil;

public class Ts_SqOverSellFullRefund {

	private static OpenapiReq openapiReq;
	
	private static SqOverSellFullRefundReq sqOverSellFullRefundReq;
	private static SqOverSellFullRefundCall sqOverSellFullRefundCall;
	
	private static OpenApiWapper openApiWapper;
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();
	private static RefundBillWrapper refundBillWrapper = new RefundBillWrapper();
	
	private static long autotest_goodsOwnerId = Long.valueOf(EnvSetup
			.getData("autotest_goodsOwnerId")); 

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("openapi超卖退货退款");
		openApiWapper = new OpenApiWapper();
	}

	@Before
	public void caseUp() {

		openapiReq = new OpenapiReq();
		
		sqOverSellFullRefundReq = new SqOverSellFullRefundReq();
		sqOverSellFullRefundCall = new SqOverSellFullRefundCall();
		
		openapiReq.setMethod("sq.order.oversell.fullrefund");
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(sqOverSellFullRefundCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}
	
	/**
	 * 
	 * @param orderIds
	 * @param orderType （1：取消订单，2：退货退款）
	 */
	public void verify(List<Long> orderIds, int orderType) {
		
		if (orderType == 1) {
			
			OrderPo orderPo = orderShardingWapper.selectOrderbyOrderId(orderIds.get(0));
			
			Logger.verifyEquals("OPENAPI取消未支付订单", orderPo.getCancelReason(), "验证取消订单原因");
		} else {
			
			for (Long orderId : orderIds) {
				
				List<RefundBill> refundBills = refundBillWrapper.selectByOrderId(orderId);
				
				RefundBill refundBill = refundBills.get(0);
				
				Logger.verifyEquals(3, refundBill.getRefund_type(), "验证Refund_type");
				Logger.verifyEquals(2, refundBill.getMch_review_status(), "验证Mch_review_status");
				Logger.verifyEquals(true, refundBill.getOver_sell(), "验证Over_sell");
			}
		}
	}
	
	@SuppressWarnings("static-access")
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SqOverSellFullRefund_001() {
		Logger.start(true, "openapi单个订单超卖退款");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder1(productBean, autotest_goodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			PaymentPo payment = orderShardingWapper
					.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(thirdTradingId, payment,
					null, 1);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			Thread.sleep(5000);

			sqOverSellFullRefundReq.setOrder_ids(Arrays.asList(orderId));
			
			Application application = openApiWapper
					.selectApplicationBySellerId(autotest_goodsOwnerId).get(0);

			String app_id = application.getApp_id();

			AuthCode authCode = openApiWapper.selectAuthCodeByAppId(app_id)
					.get(0);

			openapiReq.setApp_id(app_id);

			String app_secret = application.getApp_secret();

			openapiReq.setSign_method("MD5");
			openapiReq.setAuth_code(authCode.getAuth_code());
			openapiReq.setTimestamp(YMTDateUtil.getSysTime());
			openapiReq.setNonce_str(TestDataManager.getRandomNum(31));
			openapiReq.setBiz_content(new FormatUtil()
					.beanToGSONString(sqOverSellFullRefundReq));
			String url = String
					.format("http://apigateway.shop2cn.com/apigateway/v1?app_id=%s&method=sq.order.oversell.fullrefund",
							app_id);

			sqOverSellFullRefundCall.setUrl(url);

			openapiReq.setSign(OpenapiService.generateMD5(openapiReq,
					AesUtil.decrypt(app_secret)));

			sqOverSellFullRefundCall.setData(openapiReq);
			sqOverSellFullRefundCall.callService();

			Logger.verifyEquals("0000", sqOverSellFullRefundCall.getCode(), 
					"校验code");
			Logger.verifyEquals("操作成功", sqOverSellFullRefundCall.getMsg(),
					"校验message");

			Logger.verifyNotNull(sqOverSellFullRefundCall.getContent(),
					"校验content");
			
			this.verify(Arrays.asList(orderId), 2);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@SuppressWarnings("static-access")
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SqOverSellFullRefund_002() {
		Logger.start(true, "openapi多个订单超卖退款");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder1(productBean, autotest_goodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			PaymentPo payment = orderShardingWapper
					.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(thirdTradingId, payment,
					null, 1);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			Thread.sleep(5000);
			
			AgentProductBean productBean2 = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp2 = SqTradingCallService
					.placeOrder1(productBean2, autotest_goodsOwnerId);

			Order order2 = placeOrderResp2.getOrderList().get(0);

			long orderId2 = order2.getOrderId();

			BigDecimal amount2 = placeOrderResp2.getPayableAmount();

			// 支付订单
			Long thirdTradingId2 = SqTradingCallService.payOrder(userId,
					placeOrderResp2.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId2),
					amount2.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId2 = orderShardingWapper.selectOrderbyOrderId(orderId2)
					.getPaymentId();

			PaymentPo payment2 = orderShardingWapper
					.selectPaymentById(paymentId2);

			ShenqiSettlementService.onHpSettled(thirdTradingId2, payment2,
					null, 1);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			Thread.sleep(5000);

			sqOverSellFullRefundReq.setOrder_ids(Arrays.asList(orderId, orderId2));
			
			Application application = openApiWapper
					.selectApplicationBySellerId(autotest_goodsOwnerId).get(0);

			String app_id = application.getApp_id();

			AuthCode authCode = openApiWapper.selectAuthCodeByAppId(app_id)
					.get(0);

			openapiReq.setApp_id(app_id);

			String app_secret = application.getApp_secret();

			openapiReq.setSign_method("MD5");
			openapiReq.setAuth_code(authCode.getAuth_code());
			openapiReq.setTimestamp(YMTDateUtil.getSysTime());
			openapiReq.setNonce_str(TestDataManager.getRandomNum(31));
			openapiReq.setBiz_content(new FormatUtil()
					.beanToGSONString(sqOverSellFullRefundReq));
			String url = String
					.format("http://apigateway.shop2cn.com/apigateway/v1?app_id=%s&method=sq.order.oversell.fullrefund",
							app_id);

			sqOverSellFullRefundCall.setUrl(url);

			openapiReq.setSign(OpenapiService.generateMD5(openapiReq,
					AesUtil.decrypt(app_secret)));

			sqOverSellFullRefundCall.setData(openapiReq);
			sqOverSellFullRefundCall.callService();

			Logger.verifyEquals("0000", sqOverSellFullRefundCall.getCode(), 
					"校验code");
			Logger.verifyEquals("操作成功", sqOverSellFullRefundCall.getMsg(),
					"校验message");

			Logger.verifyNotNull(sqOverSellFullRefundCall.getContent(),
					"校验content");
			
			this.verify(Arrays.asList(orderId, orderId2), 2);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@SuppressWarnings("static-access")
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SqOverSellFullRefund_003() {
		Logger.start(true, "已经退款的订单，openapi单个订单超卖退款失败");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder1(productBean, autotest_goodsOwnerId);

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			PaymentPo payment = orderShardingWapper
					.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(thirdTradingId, payment,
					null, 1);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			RefundService.createPartAmountRefundSuccess(orderId, sellerId, paymentId, userId, BigDecimal.ONE);
			
			Thread.sleep(5000);

			sqOverSellFullRefundReq.setOrder_ids(Arrays.asList(orderId));
			
			Application application = openApiWapper
					.selectApplicationBySellerId(autotest_goodsOwnerId).get(0);

			String app_id = application.getApp_id();

			AuthCode authCode = openApiWapper.selectAuthCodeByAppId(app_id)
					.get(0);

			openapiReq.setApp_id(app_id);

			String app_secret = application.getApp_secret();

			openapiReq.setSign_method("MD5");
			openapiReq.setAuth_code(authCode.getAuth_code());
			openapiReq.setTimestamp(YMTDateUtil.getSysTime());
			openapiReq.setNonce_str(TestDataManager.getRandomNum(31));
			openapiReq.setBiz_content(new FormatUtil()
					.beanToGSONString(sqOverSellFullRefundReq));
			String url = String
					.format("http://apigateway.shop2cn.com/apigateway/v1?app_id=%s&method=sq.order.oversell.fullrefund",
							app_id);

			sqOverSellFullRefundCall.setUrl(url);

			openapiReq.setSign(OpenapiService.generateMD5(openapiReq,
					AesUtil.decrypt(app_secret)));

			sqOverSellFullRefundCall.setData(openapiReq);
			sqOverSellFullRefundCall.callService();

			Logger.verifyEquals("0000", sqOverSellFullRefundCall.getCode(), "验证Code");
			Logger.verifyEquals("已有退款，无法整单退款", sqOverSellFullRefundCall.getContent()
					.getJSONArray("results").getJSONObject(0).getString("msg"),
					"验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@SuppressWarnings("static-access")
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SqOverSellFullRefund_004() {
		Logger.start(true, "openapi未支付订单超卖退款");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrder1(productBean, autotest_goodsOwnerId);
			
			Thread.sleep(5000);

			Order order = placeOrderResp.getOrderList().get(0);

			long orderId = order.getOrderId();

			sqOverSellFullRefundReq.setOrder_ids(Arrays.asList(orderId));
			
			Application application = openApiWapper
					.selectApplicationBySellerId(autotest_goodsOwnerId).get(0);

			String app_id = application.getApp_id();

			AuthCode authCode = openApiWapper.selectAuthCodeByAppId(app_id)
					.get(0);

			openapiReq.setApp_id(app_id);

			String app_secret = application.getApp_secret();

			openapiReq.setSign_method("MD5");
			openapiReq.setAuth_code(authCode.getAuth_code());
			openapiReq.setTimestamp(YMTDateUtil.getSysTime());
			openapiReq.setNonce_str(TestDataManager.getRandomNum(31));
			openapiReq.setBiz_content(new FormatUtil()
					.beanToGSONString(sqOverSellFullRefundReq));
			String url = String
					.format("http://apigateway.shop2cn.com/apigateway/v1?app_id=%s&method=sq.order.oversell.fullrefund",
							app_id);

			sqOverSellFullRefundCall.setUrl(url);

			openapiReq.setSign(OpenapiService.generateMD5(openapiReq,
					AesUtil.decrypt(app_secret)));

			sqOverSellFullRefundCall.setData(openapiReq);
			sqOverSellFullRefundCall.callService();

			Logger.verifyEquals("0000", sqOverSellFullRefundCall.getCode(), 
					"校验code");
			Logger.verifyEquals("操作成功", sqOverSellFullRefundCall.getMsg(),
					"校验message");

			Logger.verifyNotNull(sqOverSellFullRefundCall.getContent(),
					"校验content");
			
			this.verify(Arrays.asList(orderId), 1);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@SuppressWarnings("static-access")
	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_SqOverSellFullRefund_005() {
		Logger.start(true, "openapi单个订单超卖退款");
		try {
			
			AgentProductBean productBean = DGSQBuildProxyChainCallService
					.createProxychain((int) autotest_goodsOwnerId, 0, false,
							false);

			TradingServiceResp placeOrderResp = SqTradingCallService
					.placeOrderWithExchangeCoupon(productBean, productBean.getSellerId());

			Order order = placeOrderResp.getOrderList().get(0);

			long sellerId = order.getSellerId();
			Long userId = placeOrderResp.getUserId();

			long orderId = order.getOrderId();

			BigDecimal amount = placeOrderResp.getPayableAmount();

			// 支付订单
			Long thirdTradingId = SqTradingCallService.payOrder(userId,
					placeOrderResp.getTradingId());

			// 支付网关支付回调交易
			SQPayGateWayCallService.DGSQNotifyCall(
					String.valueOf(thirdTradingId),
					amount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue(), BigDecimal.ZERO.toPlainString());

			Thread.sleep(5000);

			Long paymentId = orderShardingWapper.selectOrderbyOrderId(orderId)
					.getPaymentId();

			PaymentPo payment = orderShardingWapper
					.selectPaymentById(paymentId);

			ShenqiSettlementService.onHpSettled(thirdTradingId, payment,
					null, 1);

			// 卖家接单
			SqTradingCallService.sellerAcceptOrder(sellerId, orderId);
			
			Thread.sleep(5000);

			sqOverSellFullRefundReq.setOrder_ids(Arrays.asList(orderId));
			
			Application application = openApiWapper
					.selectApplicationBySellerId(autotest_goodsOwnerId).get(0);

			String app_id = application.getApp_id();

			AuthCode authCode = openApiWapper.selectAuthCodeByAppId(app_id)
					.get(0);

			openapiReq.setApp_id(app_id);

			String app_secret = application.getApp_secret();

			openapiReq.setSign_method("MD5");
			openapiReq.setAuth_code(authCode.getAuth_code());
			openapiReq.setTimestamp(YMTDateUtil.getSysTime());
			openapiReq.setNonce_str(TestDataManager.getRandomNum(31));
			openapiReq.setBiz_content(new FormatUtil()
					.beanToGSONString(sqOverSellFullRefundReq));
			String url = String
					.format("http://apigateway.shop2cn.com/apigateway/v1?app_id=%s&method=sq.order.oversell.fullrefund",
							app_id);

			sqOverSellFullRefundCall.setUrl(url);

			openapiReq.setSign(OpenapiService.generateMD5(openapiReq,
					AesUtil.decrypt(app_secret)));

			sqOverSellFullRefundCall.setData(openapiReq);
			sqOverSellFullRefundCall.callService();
			
			// 退款服务同步到交易
			RefundService.syncNotSyncedRefundBill();

			// 退款提交到网关
			UserRefundFundDetailPo record = new UserRefundFundDetailPo();

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.HOUR, -24);

			record.setPaymentId(paymentId);
			record.setUpdateTime(calendar.getTime());

			orderShardingWapper.userRefundFundDetailMapper
					.updateByPrimaryKeySelective(record);

			RefundService.supplementRefund(orderId);

			// 支付网关退款回调
			SQPayGateWayCallService.refundNotifyCall("13",
					paymentId.toString(), userId.intValue());

			Logger.verifyEquals("0000", sqOverSellFullRefundCall.getCode(), 
					"校验code");
			Logger.verifyEquals("操作成功", sqOverSellFullRefundCall.getMsg(),
					"校验message");

			Logger.verifyNotNull(sqOverSellFullRefundCall.getContent(),
					"校验content");
			
			this.verify(Arrays.asList(orderId), 2);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
